defmodule Servy.Parser do
  @doc "parse request headers"

  alias Servy.Conv, as: Conv

  def parse(request) do
    #TODO: Parse the request string into a map:
    [top | params_string1] = String.split(request, "\n\n")
    [ _ | params_string2] = String.split(request, "\r\n\r\n")

    params_string = [params_string1,  params_string2]
    |> Enum.filter(&!Enum.empty?(&1))
    |> List.flatten
    # params_string = List.first(params_string)
    [request_line | header_lines] = String.split(top, "\n")

    [method, path, _version] = String.split(request_line, " ")

    headers = parse_headers(header_lines, %{})

    params = parse_params(headers["Content-Type"], params_string)
    %Conv{
      method: method,
      path: path,
      headers: headers,
      params: params
    }
  end

  def parse_headers([head | tail], headers) do
    # IO.puts "Head: #{inspect(head)} Tail: #{inspect(tail)}"
    headers = case String.split(head, ":") do
      [key, value] -> Map.put(headers, String.trim(key), String.trim(value))
      _ -> headers
    end
    parse_headers(tail, headers)
  end

  def parse_headers([], headers), do: headers

  @doc """
  ## Examples
  iex> params_string = ["name=Baloo&type=Brown"]
  iex> Servy.Parser.parse_params("application/x-www-form-urlencoded", params_string)
  %{"name" => "Baloo", "type" => "Brown"}
  """
  def parse_params("application/x-www-form-urlencoded", params_list) do
    case List.first(params_list) do
      nil -> %{}
      query -> query |> String.trim |> URI.decode_query
    end
  end

  def parse_params(_, _), do: %{}
end
